<template>
  <div class="password-generator">
    <el-row justify="center">
      <el-col :xs="24" :sm="24" :md="24" :lg="22" :xl="20">
        <el-card class="box-card">
          <template #header>
            <div class="card-header">
              <el-icon color="#009688">
                <key />
              </el-icon>
              <span class="ml-2">随机密码生成器</span>
            </div>
          </template>

          <!-- 密码显示区域 -->
          <el-input
            v-model="generatedPassword"
            placeholder="生成的密码"
            readonly
            :type="showPassword ? 'text' : 'password'"
            class="mb-4"
          >
            <template #append>
              <el-button
                :icon="showPassword ? 'View' : 'Hide'"
                @click="showPassword = !showPassword"
              />
              <el-button :icon="DocumentCopy" @click="copyPassword" />
            </template>
          </el-input>

          <!-- 密码强度指示器 -->
          <div class="strength-indicator mb-4">
            <el-progress
              :percentage="passwordStrength.score"
              :status="passwordStrength.status"
              :stroke-width="8"
            />
            <span :class="`strength-text ${passwordStrength.status}`">
              {{ passwordStrength.text }}
            </span>
          </div>

          <!-- 配置选项 -->
          <div class="config-section">
            <el-row :gutter="20">
              <el-col :span="24">
                <el-form-item label="密码长度">
                  <el-slider
                    v-model="length"
                    :min="6"
                    :max="32"
                    show-input
                    @change="generatePassword"
                  />
                </el-form-item>
              </el-col>
            </el-row>

            <el-row :gutter="20">
              <el-col :xs="24" :sm="12" :md="12" :lg="6">
                <el-checkbox v-model="options.uppercase" @change="generatePassword">
                  大写字母 (A-Z)
                </el-checkbox>
              </el-col>
              <el-col :xs="24" :sm="12" :md="12" :lg="6">
                <el-checkbox v-model="options.lowercase" @change="generatePassword">
                  小写字母 (a-z)
                </el-checkbox>
              </el-col>
              <el-col :xs="24" :sm="12" :md="12" :lg="6">
                <el-checkbox v-model="options.numbers" @change="generatePassword">
                  数字 (0-9)
                </el-checkbox>
              </el-col>
              <el-col :xs="24" :sm="12" :md="12" :lg="6">
                <el-checkbox v-model="options.symbols" @change="generatePassword">
                  特殊字符 (!@#$%^&*)
                </el-checkbox>
              </el-col>
            </el-row>

            <el-button type="primary" class="mt-4 w-full" @click="generatePassword">
              <el-icon class="mr-2">
                <refresh />
              </el-icon>
              重新生成
            </el-button>
          </div>

          <!-- 历史记录 -->
          <el-collapse v-model="activeCollapse" class="mt-4">
            <el-collapse-item title="生成历史" name="1">
              <el-scrollbar max-height="200px">
                <template v-if="history.length">
                  <div v-for="(password, index) in history" :key="index" class="history-item">
                    <span class="password-text">{{ password }}</span>
                    <el-button
                      type="primary"
                      link
                      :icon="DocumentCopy"
                      @click="copyToClipboard(password)"
                    />
                  </div>
                </template>
                <el-empty v-else description="暂无历史记录" />
                <div class="text-center mt-2">
                  <el-button type="danger" link @click="clearHistory">清空历史</el-button>
                </div>
              </el-scrollbar>
            </el-collapse-item>
          </el-collapse>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue';
import { Key, Refresh, DocumentCopy } from '@element-plus/icons-vue';
import { ElNotification } from 'element-plus';

const generatedPassword = ref('');
const showPassword = ref(false);
const length = ref(16);
const history = ref([]);
const options = ref({
  uppercase: true,
  lowercase: true,
  numbers: true,
  symbols: true
});
const activeCollapse = ref(['1']);

const passwordStrength = computed(() => {
  const password = generatedPassword.value;
  if (!password) {
    return {
      score: 0,
      status: 'info',
      text: '未生成'
    };
  }

  let score = 0;
  let complexity = 0;

  // 检查长度
  if (password.length >= 12) score += 25;
  else if (password.length >= 8) score += 15;
  else score += 5;

  // 检查字符类型
  if (/[A-Z]/.test(password)) {
    score += 25;
    complexity++;
  }
  if (/[a-z]/.test(password)) {
    score += 25;
    complexity++;
  }
  if (/[0-9]/.test(password)) {
    score += 25;
    complexity++;
  }
  if (/[^A-Za-z0-9]/.test(password)) {
    score += 25;
    complexity++;
  }

  // 根据复杂度调整分数
  score = Math.min(100, score * (complexity / 4));

  // 返回强度评估
  if (score >= 80) {
    return {
      score,
      status: 'success',
      text: '强'
    };
  } else if (score >= 60) {
    return {
      score,
      status: 'warning',
      text: '中等'
    };
  } else {
    return {
      score,
      status: 'exception',
      text: '弱'
    };
  }
});

const generatePassword = () => {
  const chars = {
    uppercase: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
    lowercase: 'abcdefghijklmnopqrstuvwxyz',
    numbers: '0123456789',
    symbols: '!@#$%^&*()_+-=[]{}|;:,.<>?'
  };

  // 确保至少选择了一种字符类型
  const hasSelection = Object.values(options.value).some(value => value);
  if (!hasSelection) {
    options.value.lowercase = true;
  }

  // 构建字符集
  let charset = '';
  Object.entries(options.value).forEach(([key, value]) => {
    if (value) charset += chars[key];
  });

  // 生成密码
  let password = '';
  for (let i = 0; i < length.value; i++) {
    const randomIndex = Math.floor(Math.random() * charset.length);
    password += charset[randomIndex];
  }

  generatedPassword.value = password;
  addToHistory(password);
};

const addToHistory = password => {
  history.value.unshift(password);
  if (history.value.length > 10) {
    history.value.pop();
  }
  localStorage.setItem('passwordHistory', JSON.stringify(history.value));
};

const copyPassword = async () => {
  await copyToClipboard(generatedPassword.value);
};

const copyToClipboard = async text => {
  try {
    await navigator.clipboard.writeText(text);
    showNotification('已复制到剪贴板', 'success');
  } catch (error) {
    showNotification('复制失败', 'error');
  }
};

const clearHistory = () => {
  history.value = [];
  localStorage.removeItem('passwordHistory');
  showNotification('历史记录已清空', 'success');
};

const showNotification = (message, type = 'success') => {
  ElNotification({
    message,
    type,
    duration: 2000,
    position: 'top-right'
  });
};

onMounted(() => {
  generatePassword();
  // 从本地存储加载历史记录
  const savedHistory = localStorage.getItem('passwordHistory');
  if (savedHistory) {
    history.value = JSON.parse(savedHistory);
  }
});
</script>

<style scoped>
.password-generator {
  width: 100%;
  max-width: 1000px;
  margin: 20px auto;
  padding: 0 20px;
}

.card-header {
  display: flex;
  align-items: center;
  font-size: 1.2em;
}

.strength-indicator {
  display: flex;
  align-items: center;
  gap: 10px;
}

.strength-text {
  font-size: 0.9em;
}

.strength-text.success {
  color: var(--el-color-success);
}

.strength-text.warning {
  color: var(--el-color-warning);
}

.strength-text.exception {
  color: var(--el-color-danger);
}

.password-text {
  font-family: 'Fira Code', monospace;
  font-size: 0.9em;
}

.config-section {
  margin: 20px 0;
}

.w-full {
  width: 100%;
}

.mb-4 {
  margin-bottom: 1rem;
}

.mt-4 {
  margin-top: 1rem;
}

.ml-2 {
  margin-left: 0.5rem;
}

.mr-2 {
  margin-right: 0.5rem;
}

.flex-grow {
  flex-grow: 1;
}

.history-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 0;
  border-bottom: 1px solid var(--el-border-color-lighter);
}

.history-item:last-child {
  border-bottom: none;
}
</style>
